#Import-LocalizedData.ps1
# Auteur Jacques Barathon alias Janel. Le 20/01/2009
# http://janel.spaces.live.com/blog/cns!9B5AA3F6FA0088C2!428.entry

function Import-LocalizedData([string] $DataFileName,
                              [System.Globalization.CultureInfo] $UIculture = (Get-UIculture))

{
# La fonction ci-dessus permet d'importer des donn?es selon la culture de la session en cours ou en pr?cisant une culture particuli?re.
# Fonctionne avec PowerShell version 1. 
# 
# Chaque fichier de donn?es doit ?tre plac? dans un r?pertoire portant le nom de la culture ("fr-FR", "en-US", etc). 
# Ce r?pertoire lui-m?me doit ?tre plac? dans le m?me r?pertoire que le script. 
# 
# Par d?faut, le fichier lu aura le m?me nom que le script, avec une extension diff?rente: .psl1 (pour PowerShell Localization, v1 ).
# Mais on peut pr?ciser un autre nom de fichier. Attention ? ne pas pr?ciser l'extension, elle est rajout?e par la fonction! 
# 
# Enfin, le contenu d'un fichier doit ?tre sous la forme suivante : 
# <nom> = <valeur> 
# 
# Pour faciliter la lecture du fichier, on peut ajouter des lignes vierges et des lignes de commentaire commen?ant par #.
#
# get-content c:\tests\fr-FR\test-local.psl1
# #culture "fr-FR"
# 
# Welcome = Bienvenue au jeu "Devinez un jour" !
# Prompt  = Tapez un nom de jour
# Success = Vous avez devin? ! Toutes nos f?licitations !
# 
# get-content c:\tests\en-US\test-local.psl1
# # culture "en-US"
# Welcome = Welcome to the "Guess a day" game!
# Prompt = Enter the name of any day
# Success = You had it right! Congratulations!
#
#
# c:\tests\test-local.ps1 :
# param ([System.Globalization.CultureInfo]$myculture = (get-UIculture))
# 
# . c:\scripts\import-localizeddata.ps1
# 
# $messages = import-localizeddata -uiculture $myculture
# 
# $messages.Welcome
# $messages.Prompt
# $messages.Success


#----------------------------------------------------------------------------------------------------------------------------
#17/02/09 Laurent Dardenne
#Ajout de la gestion des caract?res de contr?les
# Pour Key = `tSuccess`r`n , sous PS v1 on doit faire : 
#  $Chaine=&$ExecutionContext.InvokeCommand.NewScriptBlock("`$ExecutionContext.InvokeCommand.ExpandString(`"$($ht.Key)`")") 
#
#  On utilise les caract?res de contr?les du C-C# et pas ceux de PowerShell
#   Key= \tSuccess\r\n.
#   Key= \TSuccess\r\n.  \T provoquera une erreur car les caract?res de contr?les sont sensible ? la casse
#   Key= \\TSuccess\r\n.  \\T est transform? en \T.
#   Key= \\tSuccess\r\n.  \\t est transform? en \t.
#
#Ajout de la gestion d'une culture par d?faut
#Ajout des membres isBasicLatin, isDefaultCulture, Get, GetCallerPath, GetCaller et GetCulture.
# usage :  
#   1) NecessaryParameter={0} : le param?tre {1} doit ?tre renseign?. 
#   2) $LogDatas.Get("NecessaryParameter","FunctionName","ParameterName")  
#   ex:  function Set-LogXMLConfigurator([String] $FileName=$(Throw $LogDatas.Get("NecessaryParameter","Set-LogXMLConfigurator","FileName")), 
  $isDefaultCulture=$False
  
  if ($DataFileName -eq [String]::Empty)
  { 
    $ParentInvocation = (Get-Variable MyInvocation -Scope 1).Value
    $DataFileName=$ParentInvocation.MyCommand 
  }
  $DataFileName= [IO.Path]::GetFileNameWithoutExtension($DataFileName)
      Write-Debug "DataFileName : $DataFileName"
      Write-Debug "UIculture : $UIculture"
  if ($myInvocation.ScriptName) 
   { 
     Write-Debug "PS V1"
     $CallerScriptName = $myInvocation.ScriptName 
   }
  else 
   { 
    Write-Debug "PS V2 ctp3. Todo : Bug ?"
    $CallerScriptName= $myInvocation.MyCommand.Definition 
    } 
  Write-Debug "CallerScriptname : $CallerScriptName"

  $CallerPath = [IO.Path]::GetDirectoryName($CallerScriptName)
      Write-Debug "CallerPath : $CallerPath"
  $CulturePath="$CallerPath\$UIculture"
      Write-Debug "Culturepath : $culturepath"
  
  if ( ($UIculture -eq $null) -or !(Test-path $CulturePath) ) 
  { 
      Write-Debug "`t* Default culture en-US *" 
    $isDefaultCulture=$True
    $UICulture = New-object System.Globalization.CultureInfo "en-US"
    $CulturePath="$CallerPath\en-US"
  }

  $FullPath = "$CulturePath\$DataFileName.psl1"
      Write-Debug "Localization : load $FullPath"
  
  if (! (Test-path $FullPath) )
   {Throw (New-Object System.IO.FileNotFoundException "Import-LocalizedData : this file do not exist : $FullPath") }
  
  $Datas = New-Object HashTable
  Get-Content $FullPath |`
    Where {($_.TrimStart()) -ne [String]::Empty -and ($_.TrimStart())[0] -ne "#"} |`
    Foreach { 
        trap [System.ArgumentException] {Write-error "$key=$value`r`n$($_.Exception.Message)";Continue}
        $key, $value = $_.Split("=", 2)
         #Transforme dans les cha?nes les caract?res de contr?le
         #En cas d'erreur de format l?ve une exception [System.ArgumentException]
            Write-Debug "Before [Regex]::Unescape $Key = $Value"
        $Value=[Regex]::Unescape($Value)
        $Datas.Add($key.Trim(), $value.TrimStart())
            Write-Debug "After [Regex]::Unescape $Key = $Value"
    }
  if ($Datas.Count -eq 0) 
   {Throw "Localization : the hashtable is empty." }
   
    #D?termine si une cha?ne de caract?re unicode, contenant la date du jour, est dans une page de code latine
  $Datas=$Datas|add-member NoteProperty isBasicLatin ((get-date -uf %A) -match "\p{IsBasicLatin}" ) -pass
    #D?termine si le fichier de donn?es est celui par d?faut
  $Datas=$Datas|add-member NoteProperty isDefaultCulture ($isDefaultCulture) -pass
     #Bug with Scriptproperty. Todo PS V2 
     #$Code="`$Datas=`$Datas| add-member Scriptproperty DataFile -value {`"$Fullpath`"} -SecondValue {Throw `"DataFile is a read only property.`"} -pass"
    #'Bypass' 
   $Code="`$Datas=`$Datas|add-member ScriptMethod GetDataFile -value {`"$Fullpath`"} -pass"
   invoke-expression $Code
  $Datas=$Datas|add-member ScriptMethod GetCulture -value {
                         $ns=[System.IO.Path]
                         $ns::GetFileNameWithoutExtension($ns::GetDirectoryName($logDatas.GetDatafile()))} -pass
   #path of the script
  $Datas=$Datas|add-member ScriptMethod GetCallerPath -value {
                                    $ns=[System.IO.Path]
                                    $ns::GetDirectoryName($ns::GetDirectoryName($this.GetDataFile()))} -pass
   #Script name
  $Datas=$Datas|add-member ScriptMethod GetCaller -value {
                                    [System.IO.Path]::GetFileNameWithoutExtension($this.GetDatafile()) } -pass
  $Datas=$Datas|add-member ScriptMethod Get {
       #Args[0] contient par convention la cl? de la Hashtable
       # -F recoit un tableau de string
     $Text=$this.Item($Args[0]) -F $Args[1..($Args.Count-1)]
       # Exemple pour l'entr?e : NullParameter={0} : le param?tre {1} est ? null.
       # $Datas.Get("NullParameter","Getlogger", "Logger")
       #Si on passe ? la fonction de formatage plus de param?tres que n?cessaire cela ne pose pas de probl?me
      
        #La culture par d?faut n'est pas latine, on formate le message avec la culture invariante.
        #"La propri?t? CultureInfo.InvariantCulture n'est ni une culture neutre, ni une culture sp?cifique. 
        #Cette culture d'un troisi?me type pourrait ?tre qualifi?e d'indiff?rente. 
        #En effet, la culture invariante est associ?e ? la langue anglaise, mais non ? un pays ou ? une r?gion".
      if ( ($this.isDefaultCulture) -and ($this.isBasicLatin -eq $false) )
       { [String]::Format([System.Globalization.CultureInfo]::InvariantCulture,"{0}",$Text) }
      else 
       {$Text}  
     } -pass 
  $Datas=$Datas|add-member ScriptMethod ExpandString{
       #Expand une cha?ne de type "[$Env:Computername] message..." 
     $ExecutionContext.InvokeCommand.ExpandString($Args[0])
     } -pass
  $Datas   
}

